#import "Screenrush.h"
#import "Constants.h"
#import "NSObject+SBJSON.h"
#import "MyControllerForPlugins.h"


// --- Defined of Preprocessor Macros of each target ---
//#define WS_API_ALLOCINE
//#define WS_API_SCREENRUSH
//#define WS_API_FILMSTARTS
//#define WS_API_SENSACINE

#ifdef WS_API_ALLOCINE
static NSString *const WS_API = @"http://api.allocine.fr/rest/v3/";
static NSString *const LABEL_USER_RATING  = @"Public";
static NSString *const LABEL_PRESS_RATING = @"Presse";
#define PLUGIN_NAME @"Allocine"
#endif

#ifdef WS_API_SCREENRUSH
static NSString *const WS_API = @"http://api.screenrush.co.uk/rest/v3/";
static NSString *const LABEL_USER_RATING  = @"Users";
static NSString *const LABEL_PRESS_RATING = @"Press";
#define PLUGIN_NAME @"Screenrush"
#endif

#ifdef WS_API_FILMSTARTS
static NSString *const WS_API = @"http://api.filmstarts.de/rest/v3/";
static NSString *const LABEL_USER_RATING  = @"User-Wertung";
static NSString *const LABEL_PRESS_RATING = @"Pressespiegel";
#define PLUGIN_NAME @"Filmstart"
#endif

#ifdef WS_API_SENSACINE
static NSString *const WS_API = @"http://api.sensacine.com/rest/v3/";
static NSString *const LABEL_USER_RATING  = @"Usuarios";
static NSString *const LABEL_PRESS_RATING = @"Medios";
#define PLUGIN_NAME @"Sensacine"
#endif

//--- Construction of parameters ---
static NSString *const WSParametersTeasersSearchURL = @"media?partner=YW5kcm9pZC12M3M&profile=large&format=json&mediafmt=mp4-lc&code=%@";
static NSString *const WSParametersMoviesSearchURL  = @"search?partner=YW5kcm9pZC12M3M&filter=movie&format=json&count=50&q=%@";
static NSString *const WSParametersMovieURL         = @"movie?partner=YW5kcm9pZC12M3M&profile=large&format=json&filter=movie&striptags=synopsis,synopsisshort&code=%@";

/********************* FR *********************/
static NSString *const TYPE_MOVIE    = @"Film";
static NSString *const TYPE_TV_SERIE = @"Série TV";

static NSString *const LIMIT_NON      = @"Aucun";
static NSString *const LIMIT_TITLE    = @"Titre";
static NSString *const LIMIT_DIRECTOR = @"Réalisateur";
static NSString *const LIMIT_ACTOR    = @"Acteur";

static NSString *const SORT_RELEVANCE = @"Pertinence";
static NSString *const SORT_TITLE     = @"Titre";
static NSString *const SORT_DATE      = @"Date";
/********************* ES *********************/
/*
 static NSString *const TYPE_MOVIE    = @"Film";
 static NSString *const TYPE_TV_SERIE = @"Série TV";
 
 static NSString *const LIMIT_NON      = @"Aucun";
 static NSString *const LIMIT_TITLE    = @"Titre";
 static NSString *const LIMIT_DIRECTOR = @"Réalisateur";
 static NSString *const LIMIT_ACTOR    = @"Acteur";
 
 static NSString *const SORT_RELEVANCE = @"Pertinence";
 static NSString *const SORT_TITLE     = @"Titre";
 static NSString *const SORT_DATE      = @"Date";
 */
/********************* UK *********************/
/*
 static NSString *const TYPE_MOVIE    = @"Film";
 static NSString *const TYPE_TV_SERIE = @"Série TV";
 
 static NSString *const LIMIT_NON      = @"Aucun";
 static NSString *const LIMIT_TITLE    = @"Titre";
 static NSString *const LIMIT_DIRECTOR = @"Réalisateur";
 static NSString *const LIMIT_ACTOR    = @"Acteur";
 
 static NSString *const SORT_RELEVANCE = @"Pertinence";
 static NSString *const SORT_TITLE     = @"Titre";
 static NSString *const SORT_DATE      = @"Date";
 */
/********************* GER ********************/
/*
 static NSString *const TYPE_MOVIE    = @"Film";
 static NSString *const TYPE_TV_SERIE = @"Série TV";
 
 static NSString *const LIMIT_NON      = @"Aucun";
 static NSString *const LIMIT_TITLE    = @"Titre";
 static NSString *const LIMIT_DIRECTOR = @"Réalisateur";
 static NSString *const LIMIT_ACTOR    = @"Acteur";
 
 static NSString *const SORT_RELEVANCE = @"Pertinence";
 static NSString *const SORT_TITLE     = @"Titre";
 static NSString *const SORT_DATE      = @"Date";
 */
/**********************************************/


enum {
	MKTypeMovie = 0,
	MKTypeTVSerie,
};

enum {
	MKLimitNone = 0,
	MKLimitTitle,
	MKLimitDirector,
    MKLimitActor
};

enum {
	MKSortRelevance = 0,
	MKSortTitre,
	MKSortDate,
};


@implementation Screenrush

- (NSString *)countryCode {
	return @"UK";
}
- (NSString *)languageCode {
	return @"en";
}

- (void)searchForString:(NSString *)aString limit:(NSInteger)aLimitNumber type:(NSInteger)typeNumber sort:(NSInteger)sortNumber sender:(id)sender {
	
	self.delegate = sender;
	[resultsTitles removeAllObjects];
	[resultsURLs removeAllObjects];
	
	aString = [aString stringByReplacingOccurrencesOfString:@" " withString:@"+"];
	NSString *encodedSearchString = [aString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSString *apiURL = [WS_API stringByAppendingString:WSParametersMoviesSearchURL];
    NSString *searchURL = [NSString stringWithFormat:apiURL, encodedSearchString];
    DLog(@"Search URL: %@", searchURL);
    
	[self downloadWebPage:searchURL];
}


- (void)searchFor:(NSDictionary *)searchDict sender:(id)sender {
    
    if ([searchDict objectForKey:@"keyword"]) { //Backward compatability
		NSString *searchTerm = [searchDict objectForKey:@"keyword"];
        [self searchForString:searchTerm limit:0 type:0 sort:0 sender:sender];
	}
	else if ([searchDict objectForKey:@"title"] != nil) {
		NSString *searchTerm = [searchDict objectForKey:@"title"];
        [self searchForString:searchTerm limit:0 type:0 sort:0 sender:sender];
	}
	else {
		[delegate searchReturnedNumberOfResults:0 sender:self];
	}
}


- (void)downloadComplete:(NSString *)HTMLSource {
	// Search the page and create a list of result titles and URLs for the details information
	// In this sample we pick all the links that start with "http"
    
    NSDictionary *result = [HTMLSource JSONValue];
    
    DLog(@"%@", result);
    
    // Error management
    if(!result) {
        ErrLog(@"JSON not parsed.\n%@", HTMLSource);
        return;
    }
    
    // Get the array of movies
    NSDictionary *root = [result objectForKey:@"feed"];
    NSArray *movies = [root objectForKey:@"movie"];
    
    if ([movies count] > 0) {
        
        // Process each movie found
        for(NSDictionary *aMovie in movies){
            // Get the originalTitles
            
            DLog(@"--- Movie information ---");
            
            NSString *strMovieTitle = [aMovie objectForKey:@"title"];
            if (strMovieTitle == nil)
                strMovieTitle = [aMovie objectForKey:@"originalTitle"];
            if(strMovieTitle == nil){
                ErrLog(@"No movie title found");
                continue;
            }
            
            //Get the code of each movie and construct the dedicated url
            NSString *movieCode = [[aMovie objectForKey:@"code"] stringValue];
            DLog(@"Movie Code : %@",movieCode);
            //Construction of the URL of the movie
            NSString *apiURL = [WS_API stringByAppendingString:WSParametersMovieURL];
            NSString *movieURL = [NSString stringWithFormat:apiURL,movieCode];
            DLog(@"Movie URL : %@",movieURL);
            [resultsURLs addObject:movieURL];
            DLog(@"Movie Title : %@", strMovieTitle);
            [resultsTitles addObject:strMovieTitle];
        }
    }
    
	[delegate searchReturnedNumberOfResults:[resultsURLs count] sender:self];
    //### Can be extended to return more than 10 results with more results and using paging
}


- (NSDictionary *)resultNumber:(int)number {
	
    //Get the details for one of the results and return it as a dictionary
    
    NSMutableDictionary *returnData = [NSMutableDictionary dictionaryWithCapacity:20];
    
	if (number >= [resultsURLs count]) {
		ErrLog(@"Error: %@ requested out of range: %d of %d", PLUGIN_NAME, number, [resultsURLs count]);
		[returnData setObject:[NSString stringWithFormat:@"No data found on %@", PLUGIN_NAME] forKey:@"title"];
		return returnData;
	}
    
    // Set Localization
    [returnData setValue:[self countryCode] forKey:@"locale"];
    [returnData setValue:[self languageCode] forKey:@"localeLanguage"];
    
	// Http request
	NSString *httpURL = [resultsURLs objectAtIndex:number];
    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:httpURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];
	NSString *HTMLSource = [[[NSString alloc] initWithData:[NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil] encoding:NSUTF8StringEncoding] autorelease];
    
    NSDictionary *results = [HTMLSource JSONValue];
    
    //DLog(@"Details: %@", results);
    
    if (results == nil) {
        ErrLog(@"Details not created.\n%@", HTMLSource);
		return nil;
    }
    
    DLog(@"--- Movie details ---");
    
    // Get the movie
    NSDictionary *movie = [results objectForKey:@"movie"];
    NSString *value;
    NSArray *values;
    
    // Get the Original Title -----
    value = [movie objectForKey:@"originalTitle"];
    if (value) {
        DLog(@"OriginalTitle : %@",value);
        [returnData setObject:value forKey:MKKeyDVDOriginalTitle];
    } else {
        DLog(@"OriginalTitle : not found");
    }
    
    // Get the Title -----
    value = [movie objectForKey:@"title"];
    if (value) {
        DLog(@"Title : %@",value);
        [returnData setObject:value forKey:MKKeyEntryTitle];
    } else {
        DLog(@"Title : not found");
    }
    
    // Get the Duration -----
    value = [movie objectForKey:@"runtime"];
    if (value) {
        NSInteger duration = [value integerValue];
        NSInteger intMinutes = round(duration/60);
        NSString *strDuration = [NSString stringWithFormat:@"%d", intMinutes];
        DLog(@"Duration : %@",strDuration);
        [returnData setObject:strDuration forKey:MKKeyDVDDuration];
    } else {
        DLog(@"Duration : not found");
    }
    
    // Get ratings
    NSString *strUserRating  = @"";
    NSString *strPressRating = @"";
    
    // Get UserRating
    value = [movie valueForKeyPath:@"statistics.userRating"];
    if (value) {
        float userRating = [value floatValue];
        DLog(@"UserRating : %@", userRating);
        strUserRating = [LABEL_USER_RATING stringByAppendingFormat:@" : %1.1f", userRating];
    } else {
        DLog(@"UserRating : not found");
    }
    
    // Get PressRating
    value = [movie valueForKeyPath:@"statistics.pressRating"];
    if (value) {
        float pressRating = [value floatValue];
        DLog(@"PressRating : %@", pressRating);
        strPressRating = [LABEL_PRESS_RATING stringByAppendingFormat:@" : %1.1f", pressRating];
    } else {
        DLog(@"PressRating : not found");
    }
    
    // Construction of the rating string
    if ([strPressRating isNotEmpty] && [strUserRating isNotEmpty])
    {
        value = [strUserRating stringByAppendingFormat:@" - %@", strPressRating];
    } else if ([strUserRating isNotEmpty])
    {
        value = strUserRating;
    } else if ([strPressRating isNotEmpty])
    {
        value = strPressRating;
    }
    
    if (value != nil)
    {
        [returnData setObject:value forKey:MKKeyDVDViewerRating];
    }
    
    // Get Rated
    value = [movie valueForKeyPath:@"movieCertificate.certificate.$"];
    if (value) {
        [returnData setObject:value forKey:MKKeyDVDRated];
    } else {
        DLog(@"Rated : not found");
    }
    
    // Get the poster
    value = [movie valueForKeyPath:@"poster.href"];
    if (value) {
        DLog(@"Poster URL : %@",value);
        [returnData setObject:value forKey:MKKeyEntryImageLocation];
    } else {
        DLog(@"Poster URL : not found");
    }
    
    // Get the Synopsis -----
    value = [movie objectForKey:@"synopsis"];
    if (value) {
        DLog(@"Synopsis : %@",value);
        [returnData setObject:value forKey:MKKeyEntrySummary];
    } else {
        DLog(@"Synopsis : not found");
    }
    
    // Get the genre -----
    values = [movie valueForKeyPath:@"genre"];
    value = [self stringFromArray:values];
    if(value != nil){
        DLog(@"Genre : %@",value);
        [returnData  setObject:value forKey:MKKeyEntryGenre];
    }
    
    
    // Get the nationality -----
    values = [movie valueForKeyPath:@"nationality"];
    value = [self stringFromArray:values];
    if(value != nil){
        DLog(@"Country : %@",value);
        [returnData  setObject:value forKey:MKKeyDVDCountry];
    }
    
    
    // Get the Directors -----
    value = [movie valueForKeyPath:@"castingShort.directors"];
    if (value) {
        DLog(@"Director : %@",value);
        [returnData setObject:value forKey:MKKeyDVDDirector];
    } else {
        DLog(@"Director : not found");
    }
    
    // Get the Studio -----
    value = [movie valueForKeyPath:@"release.distributor.name"];
    if (value) {
        DLog(@"Studio : %@",value);
        [returnData setObject:value forKey:MKKeyDVDStudio];
    } else {
        DLog(@"Studio : not found");
    }
    
    // Get the Actors -----
    value = [movie valueForKeyPath:@"castingShort.actors"];
    if (value) {
        DLog(@"Actors : %@",value);
        [returnData setObject:value forKey:MKKeyDVDStarring];
    } else {
        DLog(@"Actors : not found");
    }
    
    // Get the URL -----
    value = [[[movie objectForKey:@"link"] firstObject] objectForKey:@"href"];
    if (value) {
        DLog(@"Link : %@",value);
        [returnData setObject:value forKey:MKKeyEntryProductURL];
    } else {
        DLog(@"Link : not found");
    }
    
    // Get the aspect ratio -----
    NSArray *projections = [movie valueForKeyPath:@"formatList.projectionFormat"];
    value = [[projections firstObject] objectForKey:@"$"];
    if (value)
        [returnData setObject:value forKey:MKKeyDVDAspectRatio];
    
    value = [[[movie valueForKeyPath:@"formatList.soundFormat"] firstObject] objectForKey:@"$"];
    if (value)
        [returnData setObject:value forKey:MKKeyDVDSound];
    
    // Get the language -----
    values = [movie valueForKeyPath:@"language"];
    value = [self stringFromArray:values];
    if(value){
        [returnData  setObject:value forKey:MKKeyDVDLanguage];
    }
    
    
    NSMutableArray *creditsArray = [NSMutableArray array];
    values = [movie objectForKey:@"castMember"];
    for (NSDictionary *aCredit in values) {
        NSNumber *type = [aCredit valueForKeyPath:@"activity.code"];
        if ([type integerValue] == 8001) {
            NSString *name = [aCredit valueForKeyPath:@"person.name"];
            NSString *role = [aCredit valueForKeyPath:@"role"];
            if ([name isNotEmpty])
                [creditsArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:name, @"name", role, @"role", nil]];
        }
    }
    if ([creditsArray count])
        [returnData setValue:creditsArray forKey:@"credits"];
    
    
    /* Date formatting DVDPedia
     NSString *releaseDate = [temp_info stringBetween:@"</a> | " and:@"</td></tr>"];
     if (releaseDate) {
     NSDateFormatter *inputFormatter = [[[NSDateFormatter alloc] init] autorelease];
     [inputFormatter setDateFormat:@"yyyy-MM-dd"];
     NSDate *dateForKey = [inputFormatter dateFromString: releaseDate];
     [returnData setValue:dateForKey forKey:@"releaseDate"];
     }
     */
    
    
    // Get the Release Date -----
    value = [movie valueForKeyPath:@"release.releaseDate"];
    if (value) {
        DLog(@"Release Date : %@", value);
        [returnData setObject:value forKey:MKKeyEntryRelease];
    } else {
        DLog(@"Release Date : not found");
    }
    
    // Get the Theatrical Date -----
    NSNumber *year = [movie valueForKeyPath:@"productionYear"];
    if (year) {
        DLog(@"Theatrical Date : %@", year);
        [returnData setObject:[year stringValue] forKey:MKKeyDVDTheatrical];
    } else {
        DLog(@"Theatrical Date : not found");
    }
    
    // Get the Teaser titles and codes -----
    NSMutableDictionary *teaserDict = [NSMutableDictionary dictionary];
    NSMutableArray *teaserLinks = [NSMutableArray array];
    
    values = [movie valueForKeyPath:@"media"];
    for(NSDictionary* nextMedia in values){
        NSNumber *mediaCode = [nextMedia valueForKeyPath:@"type.code"];
        //Check that the media is a teaser code=31003
        if([[mediaCode stringValue] isEqualToString:@"31003"]){
            NSString *teaserCode;
            NSString *teaserTitle;
            teaserTitle = [nextMedia objectForKey:@"title"];
            teaserCode = [[nextMedia objectForKey:@"code"] stringValue];
            DLog(@"Movie teaser (code : %@, title : %@)",teaserCode, teaserTitle);
            [teaserDict setValue:teaserTitle forKey:teaserCode];
        }
    }
    
    // Get the URL for each teaser
    NSArray *teaserCodes = [teaserDict allKeys];
    for(NSString *teaserCode in teaserCodes){
        
        DLog(@"--- Selection of a link for teaser (%@) --- ", teaserCode);
        
        NSString *apiURL = [WS_API stringByAppendingString:WSParametersTeasersSearchURL];
        NSString *teaserSearchURL = [NSString stringWithFormat:apiURL, teaserCode];
        NSString *teaserURL=@"";
        
        // Http request
        NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:teaserSearchURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];
        NSString *results = [[[NSString alloc] initWithData:[NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil] encoding:NSUTF8StringEncoding] autorelease];
        
        if (results != nil){
            NSDictionary *teaser = [results JSONValue];
            DLog(@"%@", teaser);
            // Error management
            if(!teaser) {
                ErrLog(@"Teaser not created\n%@", results);
                return nil;
            }
            
            //DLog(@"%@",xmlDocTeaser);
            
            // Get the root element (media)
            NSDictionary *media = [teaser objectForKey:@"media"];
            //DLog(@"%@",media);
            NSInteger quality_score=0;
            
            // Get movie teasers url -----
            values = [media valueForKeyPath:@"rendition"];
            for(NSDictionary* anElement in values){
                //DLog(@"%@",xmlElement);
                
                // --- Get teaser URL candidate ---
                NSString *tmpTeaserURL = [anElement valueForKeyPath:@"href"];
                //DLog(@"tmpTeaserURLCandidate : %@", tmpTeaserURL);
                
                // --- Get the quality of teaser URL candidate ---
                NSString *tmpTeaserQuality = [[anElement valueForKeyPath:@"bandwidth.code"] stringValue];
                //DLog(@"tmpQualityOfTeaserURLCandidate : %@", tmpTeaserQuality);
                
                // Choose the best quality regarding this configuration
                // Debit standard > debit moyen > bas debit > haut debit
                // score        4 >           3 >         2 >          1
                
                // Haut debit
                if ([tmpTeaserQuality isEqualToString:@"104004"]) {
                    if(quality_score == 0){
                        quality_score = 1;
                        teaserURL = tmpTeaserURL;
                        DLog(@"Movie teaser URL : quality score : %d, %@", quality_score, teaserURL);
                    }
                }
                // Bas debit
                else if ([tmpTeaserQuality isEqualToString:@"104001"]) {
                    if(quality_score == 0){
                        quality_score = 2;
                        teaserURL = tmpTeaserURL;
                        DLog(@"Movie teaser URL : quality score : %d, %@", quality_score, teaserURL);
                        
                    } else if (quality_score < 2) {
                        DLog(@"Movie teaser URL : better quality score found : %d => 2", quality_score);
                        quality_score = 2;
                        teaserURL = tmpTeaserURL;
                        DLog(@"Movie teaser URL : quality score : %d, %@", quality_score, teaserURL);
                    }
                }
                // Debit moyen
                else if ([tmpTeaserQuality isEqualToString:@"104002"]) {
                    if(quality_score == 0){
                        quality_score = 3;
                        teaserURL = tmpTeaserURL;
                        DLog(@"Movie teaser URL : quality score : %d, %@", quality_score, teaserURL);
                        
                    } else if (quality_score < 3) {
                        DLog(@"Movie teaser URL : better quality score found : %d => 3", quality_score);
                        quality_score = 3;
                        teaserURL = tmpTeaserURL;
                        DLog(@"Movie teaser URL : quality score : %d, %@", quality_score, teaserURL);
                    }
                }
                // Debit standard
                else if ([tmpTeaserQuality isEqualToString:@"104003"]) {
                    DLog(@"Movie teaser URL : better quality score found : %d => 4", quality_score);
                    teaserURL = tmpTeaserURL;
                    DLog(@"Movie teaser URL : quality score : 4, %@", teaserURL);
                    break;
                }
                else {
                    DLog(@"No good quality found for movie teaser (%@)",teaserCode);
                    teaserURL=@"";
                }
                
                
            }
            
        }
        
        // If an url of a teaser with a good quality has been found, add it
        if([teaserURL isNotEmpty]){
            NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                                  [teaserDict valueForKey:teaserCode],
                                  @"name",
                                  teaserURL,
                                  @"url",
                                  @"Bande Annonce",
                                  @"type",
                                  nil];
            [teaserLinks addObject:dict];
        }
        else {
            DLog(@"%@",teaserURL);
            DLog(@"No teaser URL (with good quality) found for teaser (%@)",[teaserDict valueForKey:teaserCode]);
        }
    }
    
    [returnData setObject:teaserLinks forKey:MKKeyEntryArrayLinks];
    
	return returnData;
}


- (NSString *)stringFromArray:(NSArray *)anArray {
    NSString *finalString = nil;
    for(NSDictionary* aDict in anArray){
        NSString *aString = [aDict objectForKey:@"$"];
        if(finalString == nil){
            finalString = aString;
        }
        else {
            finalString = [finalString stringByAppendingFormat:@", %@", aString];
        }
    }
    return finalString;
}


@end
